package pl.edu.pb.wi.pwnography.model;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.joda.time.DateTime;

public class ParsedData extends DataHolder {
    private static final Logger log = Logger.getLogger(ParsedData.class
	    .getName());
    private static final String INITIAL_UPLOAD = "Wczytanie nowego pliku.";

    private List<ParsedDataChange> changeList;
    private String fileName;
    private int currentRevision;

    public ParsedData(Map<String, List<Object>> data, String fileName,
	    int rowCount) {
	this.data = data;
	this.fileName = fileName;
	this.rowCount = rowCount;
	changeList = new ArrayList<ParsedDataChange>();
	changeList.add(new ParsedDataChange(data, INITIAL_UPLOAD, DateTime
		.now(), 0));
	currentRevision = 0;
    }

    public int getCurrentRevision() {
	return currentRevision;
    }

    public ParsedDataChange getRevisionData(int revisionNumber)
	    throws Exception {
	if (revisionNumber < 0 || revisionNumber > changeList.size())
	    throw new Exception(String.format(
		    "Revision number %d doesn't exist.", revisionNumber));

	return changeList.get(revisionNumber);
    }

    public ParsedDataChange getCurrentRevisionData() throws Exception {
	return getRevisionData(getCurrentRevision());
    }

    public String getFileName() {
	return fileName;
    }

    public List<ParsedDataChange> getChangeList() {
	return changeList;
    }

    public Integer getRevisionNumber() {
	return changeList.size();
    }

    public String getLastChangeDate() {
	return (changeList.size() > 0) ? changeList.get(changeList.size() - 1)
		.getParsedDate() : null;
    }

    public ParsedDataChange addNewRevision(Map<String, List<Object>> data,
	    String description) {
	log.info(String.format("Adding new revision %d", changeList.size() - 1));

	Map<String, List<Object>> saveData = new LinkedHashMap<String, List<Object>>(
		this.data);
	saveData.putAll(data);
	ParsedDataChange pdc = new ParsedDataChange(saveData, description,
		DateTime.now(), getCurrentRevision());

	changeList.add(pdc);
	this.data = saveData;
	currentRevision = changeList.size() - 1;

	return pdc;
    }

    public void revertToRevision(int revisionNumber) throws Exception {
	log.info(String.format("Revision change: [old] %d -> %d [new]",
		currentRevision, revisionNumber));
	if (revisionNumber == currentRevision)
	    return;

	if (revisionNumber < 0 || revisionNumber >= changeList.size()) {
	    throw new Exception(String.format(
		    "Revision number %d doesn't exist.", revisionNumber));
	} else {
	    data = changeList.get(revisionNumber).getData();
	    currentRevision = revisionNumber;
	}
    }

    public void revertToNewestRevision() throws Exception {
	int newestRev = changeList.size() - 1;

	log.info(String.format(
		"Revision change to newest: [old] %d -> %d [new]",
		currentRevision, newestRev));

	if (currentRevision == newestRev || newestRev < 0) {
	    log.info("Current revision is newest one. No need to change it.");
	} else {
	    data = changeList.get(newestRev).getData();
	    currentRevision = newestRev;
	}
    }
}
